package com.ce.pms.system.custservice.service.impl;

import java.util.ArrayList;
import java.util.List;

import org.jmock.Expectations;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.ce.pms.base.vo.SearchVO;
import com.ce.pms.exception.BusinessException;
import com.ce.pms.system.custservice.dao.IReturnVisitItemDao;
import com.ce.pms.system.custservice.model.ReturnVisitItemDO;
import com.ce.pms.system.custservice.vo.ReturnVisitItemVO;
import com.sitechasia.webx.core.support.Page;
/**
 * 描述：测试“回访项目”service
 * @author 王浩羽
 *
 */
public class ReturnVisitItemServiceImplT extends MyJMockBaseTestCase
{
	private ReturnVisitItemServiceImpl serviceImpl;
	private IReturnVisitItemDao returnVisitItemDao;
	private ReturnVisitItemDO itemDO;
	private ReturnVisitItemVO itemVO;
	
	//常量数据
	private final Long CURRENT_ID = 2008L;
	private final String CURRENT_NAME = "oldName";
	private final String CURRENT_REMARK = "oldRemark";
	private final String CURRENT_VALIDITY = "0";
	// 有效性 1有效;0无效
	private final short CURRENT_SEQUENCE = (short)1;
	//类型: 001选择题类型;002发挥题类型
	private final String CURRENT_CLAZZ = "001";
	
	private final Long NEW_ID = 2009L;
	private final String NEW_NAME = "newName";
	private final String NEW_REMARK = "newRemark";
	private final String NEW_VALIDITY = "1";
	private final short NEW_SEQUENCE = (short)2;
	private final String NEW_CLAZZ = "002";
	
	@Before
	public void setUp() throws Exception
	{
		super.setUp();
		returnVisitItemDao = context.mock(IReturnVisitItemDao.class);
		serviceImpl = new ReturnVisitItemServiceImpl();
		serviceImpl.setReturnVisitItemDao(returnVisitItemDao);
		serviceImpl.setSysrefcodeDao(sysrefcodeDao);
		
		itemDO = new ReturnVisitItemDO();
		itemVO = new ReturnVisitItemVO();
		
		itemDO.setKeyword(CURRENT_ID);
		itemDO.setName(CURRENT_NAME);
		itemDO.setRemark(CURRENT_REMARK);
		itemDO.setSequence(CURRENT_SEQUENCE);
		itemDO.setValidity(CURRENT_VALIDITY);
		itemDO.setClazz(CURRENT_CLAZZ);
		itemDO.setSysInfo(sysInfo);
		
		//VO暂不设置ID，如果VO有ID，使用NEW_ID
		itemVO.setName(NEW_NAME);
		itemVO.setRemark(NEW_REMARK);
		itemVO.setSequence(NEW_SEQUENCE);
		itemVO.setValidity(NEW_VALIDITY);
		itemVO.setClazz(NEW_CLAZZ);
	}


	@After
	public void tearDown() throws Exception
	{
	}


	@Test
	public void testAddReturnVisitItemFail()
	{
		itemVO.setName(itemDO.getName());
		itemVO.setCreator(SYSTEM_INFO_CREATER);
		// expectations
		context.checking(new Expectations() {{
			//当名称存在时，将抛出异常，保存操作不会执行
			oneOf(returnVisitItemDao).findUniqueByName(itemVO.getName()); will(returnValue(itemDO));
			never(returnVisitItemDao).saveObject(with(any(ReturnVisitItemDO.class))); 
	    }});
		// execute
		try
		{
			boolean returnValue = serviceImpl.addReturnVisitItem(itemVO);
			fail("it should throw exception!");
		}
		catch(Exception e)
		{
			assertTrue(e instanceof BusinessException);
		}
		// verify
		context.assertIsSatisfied();
	}
	
	@Test
	public void testAddReturnVisitItemSuccess()
	{
		itemVO.setCreator(SYSTEM_INFO_CREATER);
		final int DEFAULT_OPTIONS_SIZE = 2;
		// expectations
		context.checking(new Expectations() {{
			//当名称还没有存在时，保存操作执行
			oneOf(returnVisitItemDao).findUniqueByName(itemVO.getName()); will(returnValue(null));
			oneOf(sysrefcodeDao).getDate();will(returnValue(SYSTEM_INFO_DATE_CREATED));
			oneOf(returnVisitItemDao).saveObject(with(any(ReturnVisitItemDO.class))); will(returnValue(itemDO));
	    }});
		// execute
		boolean returnValue = serviceImpl.addReturnVisitItem(itemVO);
		// verify
		context.assertIsSatisfied();
		assertTrue(returnValue);
		//TODO 看DO中是否多了两个默认选项  这里该如何测试？
//		Set<OptionsDef> optionsDefSet = itemDO.getOptionsDefSet();
//		assertTrue(DEFAULT_OPTIONS_SIZE == optionsDefSet.size());
//		OptionsDef[] optionsDefArray = (OptionsDef[])optionsDefSet.toArray();
//		assertEquals("A", optionsDefArray[0].getCode());
//		assertEquals("是", optionsDefArray[0].getDescription());
//		assertEquals("B", optionsDefArray[1].getCode());
//		assertEquals("否", optionsDefArray[1].getDescription());
	}


	@Test
	public void testDeleteReturnVisitItemByIdFail()
	{
		context.checking(new Expectations() {{
			oneOf(returnVisitItemDao).deleteObjectById(CURRENT_ID);will(throwException(new RuntimeException("被引用"))); 
	    }});
		boolean returnValue = false;
		try
		{
			returnValue = serviceImpl.deleteReturnVisitItemById(CURRENT_ID);
			fail("it should throw exception!");
		}
		catch(Exception e)
		{
			assertTrue(e instanceof BusinessException);
		}
		context.assertIsSatisfied();
		assertFalse(returnValue);
	}


	@Test
	public void testDeleteReturnVisitItemByIdSuccess()
	{
		context.checking(new Expectations() {{
			oneOf(returnVisitItemDao).deleteObjectById(CURRENT_ID);
	    }});
		boolean returnValue = false;
		try
		{
			returnValue = serviceImpl.deleteReturnVisitItemById(CURRENT_ID);
		}
		catch(Exception e)
		{
			fail("it should not throw exception!");
		}
		context.assertIsSatisfied();
		assertTrue(returnValue);
	}
	
	@Test
	public void testEditReturnVisitItemFail()
	{
		itemVO.setKeyword(CURRENT_ID);
		itemVO.setModifier(SYSTEM_INFO_NEW_MODIFIER);
		context.checking(new Expectations() {{
			//存在待修改的对象
			oneOf(returnVisitItemDao).findById(itemVO.getKeyword()); will(returnValue(null));
			//进行修改
			never(returnVisitItemDao).updateObject(with(any(ReturnVisitItemDO.class)));
	    }});
		boolean returnValue = serviceImpl.editReturnVisitItem(itemVO);
		context.assertIsSatisfied();
		assertFalse(returnValue);
	}

	@Test
	public void testEditReturnVisitItemSuccess()
	{
		itemVO.setKeyword(CURRENT_ID);
		itemVO.setModifier(SYSTEM_INFO_NEW_MODIFIER);
		final ReturnVisitItemDO itemDO_toEdit = new ReturnVisitItemDO();
		copyData(itemDO, itemDO_toEdit);
		context.checking(new Expectations() {{
			//存在待修改的对象
			oneOf(returnVisitItemDao).findById(itemVO.getKeyword()); will(returnValue(itemDO_toEdit));
			oneOf(sysrefcodeDao).getDate();will(returnValue(SYSTEM_INFO_DATE_CREATED));
			//进行修改
			oneOf(returnVisitItemDao).updateObject(itemDO_toEdit); will(returnValue(itemDO_toEdit));
	    }});
		boolean returnValue = serviceImpl.editReturnVisitItem(itemVO);
		context.assertIsSatisfied();
		assertTrue(returnValue);
		//值已经被修改
		assertEquals(itemVO.getName(), itemDO_toEdit.getName());
		assertEquals(itemVO.getRemark(), itemDO_toEdit.getRemark());
		assertEquals(itemVO.getValidity(), itemDO_toEdit.getValidity());
		assertEquals(itemVO.getClazz(), itemDO_toEdit.getClazz());
		assertTrue(itemVO.getSequence()==itemDO_toEdit.getSequence());
	}
	
	@Test
	public void testQueryAllReturnVisitItem()
	{
		//这里只做简单的size测试
		final List<ReturnVisitItemDO> doList_toReturn = new ArrayList<ReturnVisitItemDO>();
		final int LIST_SIZE = 2;
		for(int i = 0; i < LIST_SIZE; i++)
		{
			doList_toReturn.add(new ReturnVisitItemDO());
		}
		context.checking(new Expectations() {{
			oneOf(returnVisitItemDao).findAll(); will(returnValue(doList_toReturn));
	    }});
		List<ReturnVisitItemVO>  returnValue = serviceImpl.queryAllReturnVisitItem();
		context.assertIsSatisfied();
		assertTrue(LIST_SIZE == returnValue.size());
	}


	@Test
	public void testQueryReturnVisitItemListByPage()
	{
		final SearchVO searchVO = new SearchVO();
		Integer currentPage = 2; 
		Integer pageSize = 5;
		searchVO.setPageNo(currentPage);
		searchVO.setPageSize(pageSize);
		
		final Page page = new Page();
		// expectations
		context.checking(new Expectations() {{
			oneOf(returnVisitItemDao).queryByPage(searchVO); will(returnValue(page));
	    }});
		Page returnValue = serviceImpl.queryReturnVisitItemListByPage(searchVO);
		context.assertIsSatisfied();
		assertNotNull(returnValue);
	}
}
